package com.breez.shorturl.core.aop;

import com.breez.shorturl.annotations.Resubmit;
import com.breez.shorturl.constants.CacheConstant;
import com.breez.shorturl.enums.ResponseCode;
import com.breez.shorturl.exceptions.ShortUrlException;
import com.breez.shorturl.util.R;
import okhttp3.Response;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.lang.reflect.Method;
import java.util.concurrent.TimeUnit;

@Component
@Aspect
public class ResubmitAspect {
    private final Logger logger = LoggerFactory.getLogger(ResubmitAspect.class);
    @Autowired
    private RedisTemplate redisTemplate;

    @Pointcut("@annotation(com.breez.shorturl.annotations.Resubmit)")
    public void pointcut() {
    }

    @Around("pointcut()")
    public Object around(ProceedingJoinPoint joinPoint)   {
        ServletRequestAttributes sra = (ServletRequestAttributes)
                RequestContextHolder.currentRequestAttributes();
        HttpServletRequest request = sra.getRequest();
        String key = CacheConstant.RESUBMIT_PREFIX + request.getSession().getId() + "_" + request.getRequestURI();

        Method method = ((MethodSignature) joinPoint.getSignature()).getMethod();
        Resubmit resubmit = method.getAnnotation(Resubmit.class);
        if (!redisTemplate.opsForValue().setIfAbsent(key, 1, resubmit.intervalTime(), TimeUnit.SECONDS)) {
            logger.error("重复提交{}", key);
            throw new ShortUrlException(ResponseCode.RESUBMIT.getCode(), ResponseCode.RESUBMIT.getMsg());
        }

        try {
            logger.info("正常提交{}", key);
            return joinPoint.proceed();
        } catch (Throwable throwable) {
            throw new ShortUrlException(ResponseCode.RESUBMIT.getCode(), ResponseCode.RESUBMIT.getMsg());
        }
    }
}
